﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnityScriptEngine;
//using StoreClientModule;
using UnityCore;
using UploadManager;
using System.Drawing.Printing;

namespace MBBStoreClient
{
    public partial class frmNewReceivable : Form
    {
        SynchronizeData sync = new SynchronizeData();
        UnityScriptEngine.Threader t = new UnityScriptEngine.Threader();

        readDetails path = new readDetails();
        readDetails pLD = new readDetails();
        priceDetails pD = new priceDetails();

        DataTable exportChargeInvoice = new DataTable();
        DataTable exportChargeInvoiceItem = new DataTable();
        DataTable exportChargePayments = new DataTable();
        DataTable exportChargeBalance = new DataTable();
        DataTable exportProfile = new DataTable();
        DataTable extractedResult = new DataTable();

        DataTable distinctSoldTo = new DataTable();
        DataTable release = new DataTable();
        DataTable dt = new DataTable();
        DataTable tp = new DataTable();

        DataTable result = new DataTable();
        DataRow[] invoices = new DataRow[0];

        double AllInvoiceAmount = 0.0;
        bool isViewAll = false;

        DateTime endDate, startDate;
        

        public frmNewReceivable()
        {
            InitializeComponent();
            InitializeFrameSliderForm();
        }

        private void InitializeForm()
        {
            sync.ProcessCompleted += new CoreHandler(sync_ProcessCompleted);
            sync.ProcessError += new CoreHandler(sync_ProcessError);
            sync.Stores();

            path.fileNames = new List<string>();
            pD.tables = new List<DataTable>();
            btnSearch.Click += new EventHandler(btnSearch_Click);
            //grdItems.DoubleClick += new EventHandler(grdItems_DoubleClick);
            txtFilter.SelectedIndex = 0;
            btnPrint.Click +=new EventHandler(btnPrint_Click);
            chkAsOf.Click += new EventHandler(chkAsOf_Click);
            t.MethodCompleted += new EventHandler(delegate(object sender, EventArgs e)
            {
                t.SafeCall(this, delegate
                {
                    switch (sender.ToString())
                    {
                        case "extractChargeInvoices":
                            t.MethodCall(extractPayments);
                            break;
                        case "extractPayments":
                            t.MethodCall(CreateDataTable);
                            break;
                        case "CreateDataTable":
                            if (txtFilter.Text.Equals("All"))
                            {
                                grdItems.DataSource = dt;
                                FormatGrid();
                                pnlMsg.Visible = false;
                            }
                            else
                            {
                                selectQuery();
                            }
                                
                            break;
                        case "generateFinalResult":
                                grdItems.DataSource = result;
                                FormatGrid();
                                pnlMsg.Visible = false;
                            break;
                    }
                });
            });
        }
        
        void generateFinalResult()
        {
            result = dt.Clone();
            for (int i = 0; i < invoices.Length; i++)
                result.ImportRow(invoices[i]);
        }

        void selectQuery()
        {
            string fltr = txtFilter.Text;

            switch (fltr)
            {
                case "With Balance": invoices = dt.Select("[Total Balance] <> '0.00'"); break;
                case "Fully Paid": invoices = dt.Select("[Total Balance] = '0.00'"); break;
            }
            t.MethodCall(generateFinalResult);
        }

        void chkAsOf_Click(object sender, EventArgs e)
        {
            if (chkAsOf.Checked == true)
            {
                MessageBox.Show("Please Select Date ... Note: All Records will be extracted");
                txtDateTo.Enabled = false;
                isViewAll = true;
            }
            else
            {
                txtDateTo.Enabled = true;
                isViewAll = false;
            }
        }

        void txtSearch_KeyPress(object sender, KeyPressEventArgs e)
        {
            btnSearch_Click(null, null);
        }

        void btnSearch_Click(object sender, EventArgs e)
        {
            //extract data
            path.date = "";
            path.remNode = cmbStore.Text;
            path.fileNames.Clear();
            path.fileNames.Add("Charge Invoice");
            path.fileNames.Add("Charge Invoice Item");
            path.fileNames.Add("Charge Payments");
            path.fileNames.Add("Charge Balance");
            sync.ReadMany(path);
            pnlMsg.Visible = true;
        }
       
        void sync_ProcessError(string pcode, string msg)
        {
            t.SafeCall(this, delegate
            {
                MessageBox.Show(msg);
                pnlMsg.Visible = false;
            });
        }

        void sync_ProcessCompleted(string pcode, string msg)
        {
            t.SafeCall(this, delegate
            {
                switch (pcode)
                {
                    case "GetStores":
                        cmbStore.Items.AddRange(sync.stores);
                        cmbStore.SelectedIndex = 0;
                        
                        break;
                    case "ReadMany":
                        exportChargeInvoice = sync.exportTables[0];
                        exportChargeInvoiceItem = sync.exportTables[1];
                        exportChargePayments = sync.exportTables[2];
                        exportChargeBalance = sync.exportTables[3];
                        startDate = DateTime.Parse(txtDateFrom.Value.ToShortDateString());
                        endDate = DateTime.Parse(txtDateTo.Value.ToShortDateString());
                        if (exportChargeInvoice.Rows.Count > 0)
                        {
                            t.MethodCall(extractChargeInvoices);
                        }
                        else
                        {
                            DataTable nDT = new DataTable();
                            grdItems.DataSource = nDT;
                            pnlMsg.Visible = false;
                        }
                        break;
                }
            });
        }


        #region extract Data From File
        void extractChargeInvoices()
        {
            dt = new DataTable();

            dt.Columns.Clear();
            dt.Rows.Clear();

            dt.Columns.Add("Date of Invoices");
            dt.Columns.Add("Account Name");
            dt.Columns.Add("Invoice Number");
            dt.Columns.Add("Amount");
            dt.Columns.Add("P.O. Number");

            AllInvoiceAmount = 0;
            for (int i = 0; i < exportChargeInvoice.Rows.Count; i++)
            {
                DateTime exDate = DateTime.Parse(exportChargeInvoice.Rows[i]["fDate"].ToString());

                if (exDate >= startDate && exDate <= endDate && isViewAll == false)
                {
                    DataRow dr = dt.NewRow();
                    string inv = exportChargeInvoice.Rows[i]["fInvoice"].ToString(); ;
                    dr["Date of Invoices"] = exportChargeInvoice.Rows[i]["fDate"].ToString();
                    dr["Account Name"] = exportChargeInvoice.Rows[i]["fSoldTo"].ToString();
                    dr["Invoice Number"] = exportChargeInvoice.Rows[i]["fInvoice"].ToString();
                    dr["P.O. Number"] = exportChargeInvoice.Rows[i]["fPO"].ToString();
                    double totalInvoiceAmount = 0.0;
                    double amt = 0;
                    double qty = 0;
                    double unitPrice = 0;

                    for (int j = 0; j < exportChargeInvoiceItem.Rows.Count; j++)
                    {
                        qty = 0;
                        unitPrice = 0;
                        string inv_item = exportChargeInvoiceItem.Rows[j]["fInvoice"].ToString();
                        if (inv.Equals(inv_item))
                        {
                            double.TryParse(exportChargeInvoiceItem.Rows[j]["fQty"].ToString(), out qty);
                            double.TryParse(exportChargeInvoiceItem.Rows[j]["fUnitPrice"].ToString(), out unitPrice);
                            amt = qty * unitPrice;
                            totalInvoiceAmount += amt;
                        }
                    }
                    dr["Amount"] = Common.FormatCurrency(totalInvoiceAmount);
                    AllInvoiceAmount += totalInvoiceAmount;
                    dt.Rows.Add(dr);
                }
                else if (exDate <= startDate && isViewAll == true)
                {
                    DataRow dr = dt.NewRow();
                    string inv = exportChargeInvoice.Rows[i]["fInvoice"].ToString(); ;
                    dr["Date of Invoices"] = exportChargeInvoice.Rows[i]["fDate"].ToString();
                    dr["Account Name"] = exportChargeInvoice.Rows[i]["fSoldTo"].ToString();
                    dr["Invoice Number"] = exportChargeInvoice.Rows[i]["fInvoice"].ToString();
                    dr["P.O. Number"] = exportChargeInvoice.Rows[i]["fPO"].ToString();
                    double totalInvoiceAmount = 0.0;
                    double amt = 0;
                    double qty = 0;
                    double unitPrice = 0;

                    for (int j = 0; j < exportChargeInvoiceItem.Rows.Count; j++)
                    {
                        qty = 0;
                        unitPrice = 0;
                        string inv_item = exportChargeInvoiceItem.Rows[j]["fInvoice"].ToString();
                        if (inv.Equals(inv_item))
                        {
                            double.TryParse(exportChargeInvoiceItem.Rows[j]["fQty"].ToString(), out qty);
                            double.TryParse(exportChargeInvoiceItem.Rows[j]["fUnitPrice"].ToString(), out unitPrice);
                            amt = qty * unitPrice;
                            totalInvoiceAmount += amt;
                        }
                    }
                    dr["Amount"] = Common.FormatCurrency(totalInvoiceAmount);
                    AllInvoiceAmount += totalInvoiceAmount;
                    dt.Rows.Add(dr);
                }
            }

            distinctSoldTo = new DataTable();

            release = new DataTable();
            release.Columns.Clear();
            release.Rows.Clear();

            release.Columns.Add("Account Name");
            release.Columns.Add("Date of Invoices");
            release.Columns.Add("Invoice Number");
            release.Columns.Add("Amount");
            //release.Columns.Add("P.O. Number");

            distinctSoldTo = dt.DefaultView.ToTable(true, "Account Name");
            DataRow[] drs = distinctSoldTo.Select("[Account Name] LIKE '%%'", "[Account Name] ASC");

            for (int i = 0; i < drs.Length; i++)
            {
                string dAcctName = drs[i]["Account Name"].ToString();
                string dates = "";
                string invoices = "";
                string poNumbers = "";
                double totalAmountPerAcct = 0;

                for (int j = 0; j < dt.Rows.Count; j++)
                {
                    string acctName = dt.Rows[j]["Account Name"].ToString();
                    if (dAcctName.Equals(acctName))
                    {
                        totalAmountPerAcct += double.Parse(dt.Rows[j]["Amount"].ToString());
                        dates += dt.Rows[j]["Date of Invoices"].ToString() + "- ";
                        invoices += dt.Rows[j]["Invoice Number"].ToString() + "- ";
                        poNumbers += dt.Rows[j]["P.O. Number"].ToString() + "- ";
                    }
                }

                DataRow dr = release.NewRow();
                dr["Date of Invoices"] = dates;
                dr["Account Name"] = dAcctName;
                dr["Invoice Number"] = invoices;
                //  dr["P.O. Number"] = poNumbers;
                dr["Amount"] = Common.FormatCurrency(totalAmountPerAcct);
                release.Rows.Add(dr);
            }
            //return release;

        }
        #endregion

        #region payment
        void extractPayments()
        {
            tp = new DataTable();
            //get all invoices from 1 account name
            tp.Columns.Clear();
            tp.Rows.Clear();

            tp.Columns.Add("Account Name");
            //tp.Columns.Add("Date-OR Number");
            //tp.Columns.Add("Invoice Numbers-Amount");
            tp.Columns.Add("Total Amount Paid");
            tp.Columns.Add("Total Balance");
            double grandTotal = 0, grandBalance = 0;

            for (int i = 0; i < release.Rows.Count; i++)
            {
                string[] arrInvoice = new string[0];
                arrInvoice = release.Rows[i]["Invoice Number"].ToString().Split('-');
                string accountName = release.Rows[i]["Account Name"].ToString();

                string inv = "";
                string ORNumbers = "";
                string InvoiceNumberAndAmount = "";
                double totalAmount = 0;
                double balance = 0;

                for (int j = 0; j < arrInvoice.Length; j++)
                {
                    inv = arrInvoice[j].Trim();

                    for (int k = 0; k < exportChargePayments.Rows.Count; k++)
                    {
                        string eInvoice = exportChargePayments.Rows[k]["fInvoiceNumber"].ToString();
                        if (inv.Equals(eInvoice))
                        {
                            string fAmount = exportChargePayments.Rows[k]["fAmount"].ToString();
                            ORNumbers += exportChargePayments.Rows[k]["fDateReceived"].ToString() + "," + exportChargePayments.Rows[k]["fORNumber"].ToString() + "- ";
                            InvoiceNumberAndAmount += eInvoice + "-" + fAmount + "/ ";
                            totalAmount += double.Parse(fAmount);
                        }
                    }

                    for (int l = 0; l < exportChargeBalance.Rows.Count; l++)
                    {
                        string _eInvoice = exportChargeBalance.Rows[l]["fInvoice"].ToString();
                        string status = exportChargeBalance.Rows[l]["fStatus"].ToString();
                        if (inv.Equals(_eInvoice) && status.Equals("1"))
                        {
                            string fBal = exportChargeBalance.Rows[l]["fBalance"].ToString();
                            balance += double.Parse(fBal);
                        }
                    }

                }
                grandTotal += totalAmount;
                grandBalance += balance;
                DataRow dr = tp.NewRow();

                dr["Account Name"] = accountName;
                //  dr["Date-OR Number"] = ORNumbers;
                //  dr["Invoice Numbers-Amount"] = InvoiceNumberAndAmount;
                dr["Total Amount Paid"] = Common.FormatCurrency(totalAmount);
                dr["Total Balance"] = Common.FormatCurrency(balance);
                tp.Rows.Add(dr);

            }
            //txtPayment.Text = Common.FormatCurrency(grandTotal);
            //txtBal.Text = Common.FormatCurrency(grandBalance);
            
        }
        #endregion
        
        void CreateDataTable()
        {
            dt = new DataTable();
            dt.Columns.Add("Account Name");
            dt.Columns.Add("Total Charged");
            dt.Columns.Add("Total Payment");
            dt.Columns.Add("Total Balance");

            for (int i = 0; i < release.Rows.Count; i++)
            {
                DataRow dr = dt.NewRow();
                
                string acctName = release.Rows[i]["Account Name"].ToString();
                string totalCharge = release.Rows[i]["Amount"].ToString();
                string totalPayment = "", totalBalance = "";
                dr["Account Name"] = acctName;
                dr["Total Charged"] = totalCharge;

                for (int j = 0; j < tp.Rows.Count; j++)
                {
                    string pAcctName = tp.Rows[j]["Account Name"].ToString();
                    if (acctName.Equals(pAcctName))
                    {
                        totalPayment = tp.Rows[j]["Total Amount Paid"].ToString();
                        //totalBalance = tp.Rows[j]["Total Balance"].ToString();
                        j = tp.Rows.Count;
                    }
                }
                double c, p, b;
                c = double.Parse(totalCharge);
                p = double.Parse(totalPayment);
                b = c - p;
                dr["Total Payment"] = totalPayment;
                dr["Total Balance"] = Common.FormatCurrency(b);
                dt.Rows.Add(dr);
            }

        }

        void FormatGrid()
        {
            
            
            grdItems.Columns[0].Width = (grdItems.Width * 50) / 100;
            grdItems.Columns[1].Width = (grdItems.Width * 15) / 100;
            grdItems.Columns[2].Width = (grdItems.Width * 15) / 100;
            grdItems.Columns[3].Width = (grdItems.Width * 15) / 100;

            grdItems.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            grdItems.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            grdItems.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            grdItems.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;

            if (grdItems.Rows.Count > 0)
            {
                for (int i = 0; i < grdItems.Rows.Count; i++)
                {
                    double b;
                    b = double.Parse(grdItems.Rows[i].Cells[3].Value.ToString());
                    if (b < 0)
                    {
                        grdItems.Rows[i].Cells[3].Style.ForeColor = Color.Red;
                    }
                    else if (b > 0)
                    {
                        grdItems.Rows[i].Cells[3].Style.ForeColor = Color.Blue;
                    }
                }
            }
        }

        void grdItems_DoubleClick(object sender, EventArgs e)
        {
            Common.parent.ViewPO(grdItems.Rows[grdItems.SelectedRows[0].Index].Cells[0].Value.ToString(), cmbStore.Text);
        }

        //printing
        int cnt = 0;
        int pp = 1;
        int pageNum = 1;
        double gTC = 0, gTP = 0, gTB = 0;
        void btnPrint_Click(object sender, EventArgs e)
        {
            gTC = 0;
            gTP = 0;
            gTB = 0;
            if (grdItems.Rows.Count > 0)
            {
                PrintDocument pd = new PrintDocument();
                pd.DocumentName = lblText.Text;
                pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
                PrintDialog pdlg = new PrintDialog();
                pdlg.Document = pd;
                if (pdlg.ShowDialog() == DialogResult.OK)
                {
                    PrintPreviewDialog ppdlg = new PrintPreviewDialog();
                    ppdlg.Document = pd;
                    ppdlg.ShowDialog();
                }
            }
        }
        
        void pd_PrintPage(object sender, PrintPageEventArgs e)
        {
            float lpp = 0;
            float y = 0, y2 = 0, tmp = 0;
            float tm = e.MarginBounds.Top;
            float lm = e.MarginBounds.Left;
            float rm = e.PageBounds.Width - 100;
            float bm = e.PageBounds.Height - 100;
            float ht = 0;
            Font cFont;
            StringFormat sf = new StringFormat();
            float tmpStx = 0;

            //Header
            y = 150;
            y2 = 150;

            cFont = new Font("Courier New", 12f, FontStyle.Bold);
            ht = cFont.GetHeight(e.Graphics);
            sf.Alignment = StringAlignment.Center;
            e.Graphics.DrawString(cmbStore.Text, new Font("Courier New", 15f, FontStyle.Bold), Brushes.Black, e.PageBounds.Width / 2, 50, sf);

            sf.Alignment = StringAlignment.Center;
            e.Graphics.DrawString("STATEMENT OF ACCOUNT SUMMARY", new Font("Courier New", 15f, FontStyle.Bold), Brushes.Black, e.PageBounds.Width / 2, 90, sf);

            sf.Alignment = StringAlignment.Near;
            string str = "";
            e.Graphics.DrawString(str, cFont, Brushes.Black, lm, y, sf);

            sf.Alignment = StringAlignment.Far;
            if (isViewAll == false)
                e.Graphics.DrawString("From " + txtDateFrom.Text + " To " + txtDateTo.Text + " - Page - "+pageNum, cFont, Brushes.Black, rm, y, sf);
            else
                e.Graphics.DrawString("As Of " + txtDateFrom.Text + " - Page - " + pageNum, cFont, Brushes.Black, rm, y, sf);
            //Column Header
            y += ht;
            y2 += ht;

            e.Graphics.FillRectangle(Brushes.LightGray, lm, y, rm - lm, ht);
            e.Graphics.DrawRectangle(new Pen(Brushes.Black), lm, y, rm - lm, ht);


            sf.Alignment = StringAlignment.Center;
            float cx = lm + (((rm - lm) * 25) / 100);
            float tx = lm + (((rm - lm) * 12.5f) / 100);
            e.Graphics.DrawLine(new Pen(Brushes.Black), cx, y, cx, y + ht);
            e.Graphics.DrawString("Account Name", cFont, Brushes.Black, tx, y, sf);

            cx += ((rm - lm) * 25) / 100;
            tx = cx - ((rm - lm) * 25) / 200;
            e.Graphics.DrawLine(new Pen(Brushes.Black), cx, y, cx, y + ht);
            e.Graphics.DrawString("Total Charge", cFont, Brushes.Black, tx, y, sf);

            cx += ((rm - lm) * 25) / 100;
            tx = cx - ((rm - lm) * 25) / 200;
            e.Graphics.DrawLine(new Pen(Brushes.Black), cx, y, cx, y + ht);
            e.Graphics.DrawString("Total Payment", cFont, Brushes.Black, tx, y, sf);

            tx += ((rm - lm) * 25) / 100;
            e.Graphics.DrawString("Total Balance", cFont, Brushes.Black, tx, y, sf);

            //Data
            double tC = 0, tP = 0, c, p, b, tB=0;
            

            y += ht * (1.5f);
            y2 += ht * (1.5f);
            ht = cFont.GetHeight(e.Graphics);
            lpp = (bm - y) / ht;
            int cl = 0;
            float stx = 0, stx2 = 0;
            cFont = new Font("Courier New", 11f, FontStyle.Regular);
            while (cl <= lpp && cnt < grdItems.Rows.Count)
            {
                sf.Alignment = StringAlignment.Near;
                stx = lm + 1;
                stx2 = lm + ((rm - lm) * 56) / 100;

                str = grdItems.Rows[cnt].Cells["Account Name"].Value.ToString();
                if (str.Length > 17)
                    str = str.Substring(0, 14) + "...";
                e.Graphics.DrawString(str, cFont, Brushes.Black, stx, y, sf);

                sf.Alignment = StringAlignment.Far;
                stx += ((rm - lm) * 49) / 100;
                
                c = double.Parse(grdItems.Rows[cnt].Cells["Total Charged"].Value.ToString());
                tC += c;
                str = grdItems.Rows[cnt].Cells["Total Charged"].Value.ToString();
                e.Graphics.DrawString(str, cFont, Brushes.Black, stx, y, sf);
                y += ht;

                stx += ((rm - lm) * 25) / 100;
                str = grdItems.Rows[cnt].Cells["Total Payment"].Value.ToString();
                e.Graphics.DrawString(str, cFont, Brushes.Black, stx, y2, sf);
                p = double.Parse(grdItems.Rows[cnt].Cells["Total Payment"].Value.ToString());
                tP += p;

                stx += ((rm - lm) * 25) / 100;
                str = grdItems.Rows[cnt].Cells["Total Balance"].Value.ToString();
                e.Graphics.DrawString(str, cFont, Brushes.Black, stx, y2, sf);
                y2 += ht;
                b = double.Parse(grdItems.Rows[cnt].Cells["Total Balance"].Value.ToString());
                tB += b;

                cnt++;
                cl++;
            }

            if (y2 >= y)
            {
                tmp = y2;
                tmpStx = stx2;
            }
            else
            {
                tmp = y;
                tmpStx = stx;
            }

            tmpStx = lm + ((rm - lm) * 49) / 100; 
            
            if (cnt < grdItems.Rows.Count)
            {
                sf.Alignment = StringAlignment.Far;
                e.Graphics.DrawString(Common.FormatCurrency(tC), cFont, Brushes.Blue, tmpStx, tmp, sf);
                tmpStx += ((rm - lm) * 25) / 100;
                e.Graphics.DrawString(Common.FormatCurrency(tP), cFont, Brushes.Blue, tmpStx, tmp, sf);
                tmpStx += ((rm - lm) * 25) / 100;
                e.Graphics.DrawString(Common.FormatCurrency(tB), cFont, Brushes.Blue, tmpStx, tmp, sf);

                gTC = gTC + tC;
                gTP = gTP + tP;
                gTB = gTB + tB;

                tC = 0;
                tP = 0;
                tB = 0;
                e.HasMorePages = true;
                pageNum++;
                pp++;
            }
            else
            {
                gTC = gTC + tC;
                gTP = gTP + tP;
                gTB = gTB + tB;

                sf.Alignment = StringAlignment.Far;
                e.Graphics.DrawString(Common.FormatCurrency(tC), cFont, Brushes.Blue, tmpStx, tmp, sf);
                e.Graphics.DrawString(Common.FormatCurrency(gTC), cFont, Brushes.Red, tmpStx, tmp + ht, sf);
                tmpStx += ((rm - lm) * 25) / 100;
                e.Graphics.DrawString(Common.FormatCurrency(tP), cFont, Brushes.Blue, tmpStx, tmp, sf);
                e.Graphics.DrawString(Common.FormatCurrency(gTP), cFont, Brushes.Red, tmpStx, tmp + ht, sf);
                tmpStx += ((rm - lm) * 25) / 100;
                e.Graphics.DrawString(Common.FormatCurrency(tB), cFont, Brushes.Blue, tmpStx, tmp, sf);
                e.Graphics.DrawString(Common.FormatCurrency(gTB), cFont, Brushes.Red, tmpStx, tmp + ht, sf);
                
                
                e.HasMorePages = false;
                cnt = 0;
                pp = 1;
                pageNum = 1;
            }

        }
        
    }
}
